<?php
// +---------------------------------------------------------------------------+
// | This file is part of the KnowledgebasePublisher package                   |
// | KnowledgebasePublisher - web based knowledgebase publisher tool           |
// |                                                                           |
// | Author:  Evgeny Leontev <eleontev@gmail.com>                              |
// | Copyright (c) 2005 Evgeny Leontev                                         |
// |                                                                           |
// | For the full copyright and license information, please view the LICENSE   |
// | file that was distributed with this source code.                          |
// +---------------------------------------------------------------------------+

//require_once APP_MODULE_DIR . 'knowledgebase/category/inc/KBCategoryModel.php';
require_once APP_MODULE_DIR . 'setting/inc/SettingModel.php';
require_once 'core/app/DataToValueModel.php';
require_once 'eleontev/Util/TreeHelper.php';


class KBClientModel extends BaseModel
{
	
	var $tbl_pref_custom = 'kb_';
	var $tables = array('entry', 'category', 'entry_to_category', 'comment', 'rating', 
	                    'glossary', 'attachment_to_entry', 'related_to_entry');
						
	var $custom_tables = array('user',
							   'feedback',
							   'file_entry', 
							   'file_entry_to_category',
							   'data_to_value'=>'data_to_user_value');
	
	var $use_registration = false;
	var $is_registered = false;
	var $user_id;
    var $user_role_id;
	var $search_params;

	var $categories = array();
	var $is_private_category = false;	
	var $role_skip_categories = array();
	var $is_closed_entry = false;
	
	
	// for select article
	var $sql_params = 1;
	var $sql_params_order = '';
	var $sql_params_select = 1;
	var $sql_params_ar = array();
	
	
	// sessions name
	var $session_vote_name = 'kb_vote_';
	var $session_view_name = 'kb_view_';
	
	// rules id in data to user rule
	var $entry_member_role_rule = 12;
	
	
	
	// ATTACHMENT // ----------------------
	
	function getAttachmentList($entry_id) {
		
		$sql = "
		SELECT 
			f.id,
			f.filesize,
			f.title,
			f.filename
		FROM 
			{$this->tbl->file_entry} f,
			{$this->tbl->attachment_to_entry} ae
		WHERE 1
			AND f.id = ae.attachment_id
			AND (ae.attachment_type = 1 OR ae.attachment_type = 3)
			AND ae.entry_id = %d
			AND f.active =1";
		
		$sql = sprintf($sql, $entry_id);
		$result = &$this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();
	}
	
	
	//  is downloaded file is realy attached to article
	function isAttachment($entry_id, $file_id) {
		$sql = "
		SELECT 
			a.attachment_id
		FROM 
			{$this->tbl->attachment_to_entry} a
		WHERE 1
			AND a.entry_id = %d
			AND a.attachment_id = %d";
		
		$sql = sprintf($sql, $entry_id, $file_id);
		$result = &$this->db->Execute($sql) or die(db_error($sql));
		return $result->Fields('attachment_id');	
	}	
	
	
	// SETTINGS // ------------------------	
	
	function &getSettings($module_id, $module_name = false) {
		$s = &new SettingModel();
		$s->module_id = $module_id;
		$s->module_name = $module_name;
		return $s->getSettings();
	}
	
	
	function getSetting($setting_key) {
		return $this->setting[$setting_key];
	}
	
	
	// USER // ------------------------
	
	function getUserInfo($user_id) {
		require_once APP_MODULE_DIR . 'member/inc/MemberModel.php';
		$u = new MemberModel;
		return $u->getById($user_id);
	}
	
	
	function setUserActive($user_id) {
		$sql = "UPDATE {$this->tbl->user} SET active = 1 WHERE id = '$user_id'";
		return $this->db->Execute($sql) or die(db_error($sql));
	}
	
	
	function isUser($confirm_str, $user_id = false) {
		$sql = "SELECT id FROM {$this->tbl->user} WHERE MD5(email) = '$confirm_str'";
		$result =& $this->db->SelectLimit($sql, 1) or die(db_error($sql));
		return $result->Fields('id');
	}
	
	
	// to know do we need to user registration or not
	// it is used in some plases
	function isUseRegistration() {
		if($this->getSetting('allow_comments')   == 2 || 
		   $this->getSetting('allow_contact')    == 2 ||
		   //$this->getSetting('allow_post_entry') == 2 ||
		   $this->getSetting('kb_register_access')    || 
		   $this->is_private_category) {
			return true;
		} else {
			return $this->isPrivateEntry();
		}
	}
	
	
	
	// ADMIN // ------------------------
	
	function getAdminInfo($user_id) {
		require_once APP_MODULE_DIR . 'user/inc/UserModel.php';
		$u = new UserModel;
		return $u->getById($user_id);
	}
	
	
	// CATEGORIES // ------------------------
	
/*
	function _getCategoryListSql($parent_id) {
	
		$private_sql = $this->getPrivateSql();
		$role_skip_sql = $this->getCategoryRolesSql();
		$sort = $this->getSetting('category_sort_order');
		
		$sql = "
		SELECT 
			c.*,
			COUNT(DISTINCT cp.id) AS num_subcategories,
			COUNT(DISTINCT e.id) AS num_entries
		FROM 
			{$this->tbl->category} c
		LEFT JOIN {$this->tbl->entry_to_category} ec ON c.id = ec.category_id 
		LEFT JOIN {$this->tbl->entry} e ON e.id = ec.entry_id AND e.active = 1
		LEFT JOIN {$this->tbl->category} cp ON c.id = cp.parent_id
		
		WHERE 1
			AND c.parent_id = '{$parent_id}' 
			AND c.active = 1
			AND {$private_sql}
			AND {$role_skip_sql}
		GROUP BY c.id
		ORDER BY {$sort}";
		
		echo "<pre>"; print_r($sql); echo "</pre>";
		return $sql;
	}
*/

	// when select entry_id to find his category with help session
	function getCategoryIdsByEntryId($entry_id) {
		$sql = "SELECT category_id AS c_id,  category_id
		FROM {$this->tbl->entry_to_category}
		WHERE entry_id = '{$entry_id}'
		ORDER BY is_main DESC";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();			
	}	
	
	
	function getCategoryRssData() {
	
		$sort = $this->getSetting('category_sort_order');
		$rss_setting = $this->getSetting('rss_generate');
	
		$params = '1';
		if($rss_setting == 'top') {
			$params = "parent_id = 0";
		}
	
		$sql = "SELECT id, name AS title, description FROM {$this->tbl->category}
		WHERE active = 1
		AND private = 0
		AND {$params}
		ORDER BY {$sort}";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();	
	}
	

	function _getCategoryListSql($parent_id) {
	
		$private_sql = $this->getPrivateSql();
		$role_skip_sql = $this->getCategoryRolesSql();
		$sort = $this->getSetting('category_sort_order');
		
		$sql = "
		SELECT 
			c.*
		FROM 
			{$this->tbl->category} c
		WHERE 1
			AND c.parent_id = '{$parent_id}' 
			AND c.active = 1
			AND {$private_sql}
			AND {$role_skip_sql}
		ORDER BY {$sort}";
		
		//echo "<pre>"; print_r($sql); echo "</pre>";
		return $sql;
	}
	
	
	function &getCategoryList($parent_id = 0) {
		
		$data = array();
		$sql = $this->_getCategoryListSql($parent_id);
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		while($row = $result->FetchRow()){
			//if($row['num_entries'] == 0 && $row['num_subcategories'] == 0) { continue; }
			$data[$row['id']] = $row;
		}

		return $data;
	}
	
	
	function countEntriesPerCategory($category_ids) {
	
		$private_sql = $this->getPrivateSql('count');
	
		$sql = "
		SELECT 
			e_to_cat.category_id,
			COUNT(*)
		FROM 
			({$this->tbl->entry} e, 
			{$this->tbl->entry_to_category} e_to_cat)
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE 1
			AND e_to_cat.category_id IN($category_ids)
			AND e.id = e_to_cat.entry_id
			AND e.active = 1
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$private_sql}
		GROUP BY e_to_cat.category_id";
		
		//echo "<pre>"; print_r($sql); echo "</pre>";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();
	}
	
		
	function setCategories($sort = false) { 
	
		$this->role_skip_categories = &$this->getCategoriesNotInUserRole();
		$private_sql = $this->getPrivateSql();
		$sort = $this->setting['category_sort_order'];
	
		$sql = "SELECT id, parent_id, name, sort_order, private 
		FROM {$this->tbl->category} c
		WHERE c.active = 1
		ORDER BY {$sort}";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		while($row = $result->FetchRow()) {
			$this->categories[$row['id']] = $row;
			if($row['private']) {
				$this->is_private_category = true;
				if($private_sql != 1 || isset($this->role_skip_categories[$row['id']])) {
					unset($this->categories[$row['id']]);
				}
			}
		}
		
		//if(!$this->isExtra('private')) {
		//	$this->is_private_category = false;
		//}
	}
	
	
	function &getCategorySelectRange($arr, $parent_id = 0, $pref = '-- ') {
		if(!$arr) { return array(); }
		
		$tree_helper = &$this->getTreeHelperArray($arr, $parent_id);
		foreach($tree_helper as $id => $level) {
	
			$p = ($level == 0) ? '' : str_repeat($pref, $level);
			$data[$id] = $p . $arr[$id]['name'];
		}
		
		return $data;
	}
	
	function &getCategoryTreeRange($arr, $parent_id = 0) {
		if(!$arr) { return array(); }
 		$tree_helper = &$this->getTreeHelperArray($arr, $parent_id);
        $data[0] = 'a = new dTree("a");
a.config.useStatusText=true;
a.config.closeSameLevel=true;
a.config.useCookies=false;
a.add(0,-1,"<b>%s</b>", basehref+""); ';
		foreach($tree_helper as $id => $level) {
			$data[$id] = 'a.add(' . $id . ', ' . $arr[$id]['parent_id'] . ', "' . $arr[$id]['name'] . '",basehref+"' . $id . '/", "' . $arr[$id]['name'] . '");
';
		}
        
		return $data;
	}
	
	function &getTreeHelperArray($arr, $parent_id = 0) {
		if(!$arr) { return array(); }
		
		$tree = &new TreeHelper();
		foreach($arr as $k => $row) {
			$tree->setTreeItem($row['id'], $row['parent_id']);
		}
		
		return $tree->getTreeHelper($parent_id);
	}		
	
	
	function getPrivateSql($category = true) {
		$sql = '1';
		//if(!$this->isExtra('private')) { return $sql; }
		
		if($this->getSetting('private_policy') == 1 && !$this->is_registered) {
			if($category === 'count') {
				$sql = 'e.private = 0';
			} else {
				$sql = ($category) ? 'c.private = 0' : 'cat.private = 0 AND e.private = 0';
			}
		}
		
		return $sql;
	}
		
	
	// CATEGORY ROLES // ---------------------------
	
	function isPrivateCategory($category_id) {
		$ret = false;
		if($this->is_private_category) {
			if(!isset($this->categories[$category_id])) { // no category in categories = closed category/hidden
				$ret = 'hidden';
				
			} elseif($this->categories[$category_id]['private'] == 1 && !$this->is_registered) {
				$ret = 'display';
			}
		}
		
		return $ret;
	}
	
	
	function &getCategoriesNotInUserRole($entries_ids = false) {
		$data = array();
		if(!$this->isExtra('private')) { return $data; }
		
		$m = DataToValueModel::instance();
		foreach($m->getDataIds('kb_category_to_member_role', $entries_ids) as $cat_id => $roles) {
			if(!in_array($this->user_role_id, $roles)) {
				$data[$cat_id] = $cat_id;
			}
		}
		
		return $data;
	}
	
	
	function getCategoryRolesSql($category = true) {
		$role_skip_sql = 1;
		$field = ($category) ? 'c.id' : 'cat.id';
		if($this->role_skip_categories) {
			$role_skip_sql = sprintf('%s NOT IN(%s)', $field, implode(',', $this->role_skip_categories));
		}
		
		return $role_skip_sql;
	}
	
	
	// ARTICLES // ------------------------	
	
	function getEntriesSql($body_words = 100) {
		
		$body_words_sql = ($body_words != 'all') 
						  ? "SUBSTRING_INDEX(e.body,' ',$body_words)" 
						  : 'body'; 
		
		$sql = "
		SELECT 
			e.*,
			{$body_words_sql} AS body, 
			cat.id AS category_id,
			cat.name AS category_name,
			cat.active AS category_active,
			cat.private AS category_private,
			cat.commentable,
			cat.ratingable,
			r.votes AS votes,
			(r.rate/r.votes) AS rating,
			#IFNULL(SUM(c.active), 0) AS comment_num,
			IF(SUM(c.active) IS NULL, 0, FORMAT(SUM(c.active)/COUNT(DISTINCT cat.id), 0)) AS comment_num,
			UNIX_TIMESTAMP(e.date_updated) AS ts_updated,
			UNIX_TIMESTAMP(e.date_posted) AS ts_posted
		
		FROM 
			({$this->tbl->entry} e, 
			{$this->tbl->category} cat,
			{$this->tbl->entry_to_category} e_to_cat)
		
		LEFT JOIN {$this->tbl->comment} c ON e.id = c.entry_id
		LEFT JOIN {$this->tbl->rating} r ON e.id = r.entry_id
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE 1
			AND e.id = e_to_cat.entry_id
			AND cat.id = e_to_cat.category_id
			AND e.active = 1
			AND cat.active = 1
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$this->sql_params}
		GROUP BY e.id	
		{$this->sql_params_order}";
		
		//echo "<pre>"; print_r($sql); echo "</pre>";
		return $sql;
	}
	
	
	function getEntryCountSql() {
		
		$sql = "SELECT COUNT(*)
		FROM 
			({$this->tbl->entry} e, 
			{$this->tbl->category} cat,
			{$this->tbl->entry_to_category} e_to_cat)
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE 1
			AND e.active = 1
			AND cat.active = 1
			AND e.id = e_to_cat.entry_id
			AND cat.id = e_to_cat.category_id
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$this->sql_params}";
		
		//echo "<pre>"; print_r($sql); echo "</pre>";
		return $sql;
	}
	
		
	function getEntriesCategory($category_id, $entry_id, $limit_num) {
		
		$private_sql = $this->getPrivateSql(false);
		//$limit_sql = ($limit_num == 'all') ? '' : sprintf('LIMIT %d', $limit_num);
		
		$sql = "SELECT DISTINCT e.id AS entry_id, e.title, e.private 
		FROM 
			({$this->tbl->entry} e,
			{$this->tbl->category} cat,
			{$this->tbl->entry_to_category} e_to_cat)
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE e.active = 1
			AND cat.active = 1
			AND e.id = e_to_cat.entry_id
			AND cat.id = e_to_cat.category_id 
			AND cat.id = %d
			AND e.id != %d
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$private_sql}";
	
/*
		$sql = "SELECT DISTINCT e.id AS entry_id, e.title, e.private 
		FROM 
			({$this->tbl->entry} e,
			{$this->tbl->entry_to_category} e_to_cat)
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE e.active = 1
			AND e.id = e_to_cat.entry_id
			AND e_to_cat.category_id = %d
			AND e.id != %d
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$private_sql}";
*/
					
		$sql = sprintf($sql, $category_id, $entry_id);
		//echo "<pre>"; print_r($sql); echo "</pre>";
		
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetArray();
	}
	
	
/*
	function isRelated($entry_id) {
		$sql = "SELECT COUNT(*) AS num 
		FROM {$this->tbl->related_to_entry} r WHERE r.entry_id = %d";
		$sql = sprintf($sql, $entry_id);
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->Fields('num');	
	}
*/	
	
	
	function getEntriesRelated($entry_id) {
		
		$private_sql = $this->getPrivateSql(false);
		$private_sql .= ' AND ' . $this->getCategoryRolesSql(false);
		
		if(1) {
			$select_sql  = "IF(r.related_entry_id = %d, r.entry_id, r.related_entry_id)";
			$where_sql_1 = "(r.entry_id = %d OR r.related_entry_id = %d)";
			$where_sql_2 = "IF(r.related_entry_id = %d, e.id = r.entry_id, e.id = r.related_entry_id)";
		} else {
			$select_sql  = "r.related_entry_id AS entry_id";
			$where_sql_1 = "r.entry_id = %d";
			$where_sql_2 = "e.id = r.related_entry_id";
		}
		
		$sql = "
		SELECT DISTINCT 
			{$select_sql} AS entry_id, 
			cat.id AS category_id,
			cat.private AS category_private,
			e.title, 
			e.private,
			r.related_type
		
		FROM 
			({$this->tbl->entry} e, 
			{$this->tbl->category} cat,
			{$this->tbl->entry_to_category} e_to_cat,
			{$this->tbl->related_to_entry} r)
		LEFT JOIN {$this->tbl->data_to_value} du ON e.id = du.data_value 
		                                        AND du.rule_id = '{$this->entry_member_role_rule}'
		
		WHERE 1
			AND e.active = 1
			AND cat.active = 1
			AND e.id = e_to_cat.entry_id
			AND cat.id = e_to_cat.category_id
			AND e_to_cat.is_main = 1		
			AND {$where_sql_1}
			AND {$where_sql_2}
			AND r.related_type IN(1,3)				
			AND IF(du.user_value, du.user_value = '{$this->user_role_id}', 1)
			AND {$private_sql}";		
		
		
		$sql = sprintf($sql, $entry_id, $entry_id, $entry_id, $entry_id);
		//echo "<pre>"; print_r($sql); echo "</pre>";
		
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetArray();
	}
	
	
/*
	// select categories to entries when parse article, parsing inline related 
	function getCategoriesRelated($entry_id) {
		$sql = "
		SELECT DISTINCT 
			e.related_entry_id, 
			e_to_cat.category_id 
		FROM 
			s_kb_related_to_entry e, 
			s_kb_entry_to_category e_to_cat
		
		WHERE 1
			AND e.entry_id = %d
			AND e.related_type IN(2,3)
			AND e_to_cat.entry_id = e.related_entry_id";
		
		$sql = sprintf($sql, $entry_id);
		//echo "<pre>"; print_r($sql); echo "</pre>";
		
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();		
	}
*/
	
	
	function &getEntryList($limit, $offset, $body_words = 70) {	

		$sql = $this->getEntriesSql($body_words);
		$result =& $this->db->SelectLimit($sql, $limit, $offset) or die(db_error($sql));
		return $result->GetArray();
	}
	
	
	function &getEntryById($entry_id, $category_id) {
		
		$this->setSqlParams(sprintf("AND e.id = %d AND cat.id = %d", $entry_id, $category_id));
		$this->setSqlParams('AND ' . $this->getPrivateSql(false));
		$this->setSqlParams('AND ' . $this->getCategoryRolesSql(false));
				   
		$sql = $this->getEntriesSql('all');
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->FetchRow();
	}
	
	
	// check if any private entries or concrete entry is private
	function isPrivateEntry($entry_id = false) {
		if(!$this->isExtra('private')) { return false; }
		$params = ($entry_id) ? sprintf('id = %d', $entry_id) : '1';
		$sql = "SELECT id FROM {$this->tbl->entry} WHERE private = 1 AND {$params} LIMIT 1";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->Fields('id');
	}
	
	
	// GLOSSARY // ------------------------------	
	
	function &getGlossaryItems() {
		$sql = "SELECT g.id, g.phrase FROM {$this->tbl->glossary} g";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();
	}
	
	
	function getGlossaryDefinitions($ids = false) {
	
		$params = ($ids) ? "AND id IN ($ids)" : "";
		$this->setSqlParams($params, '', true);
	
		$sql = "SELECT g.phrase, g.definition, g.display_once
		FROM {$this->tbl->glossary} g
		WHERE {$this->sql_params}
		ORDER BY g.phrase";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();		
	}
	
	
	function isGlossary() {
		$sql = "SELECT COUNT(*) AS num FROM {$this->tbl->glossary} g";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->Fields('num');
	}
	
	
	function getGlossaryLetters() {
		$sql = "SELECT id, phrase FROM {$this->tbl->glossary} ORDER BY phrase";
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->GetAssoc();		
	}
	
	
	// COMMENTS // ------------------------------	
	
	function getCommentListSql($entry_id) {
		$sql = "
		SELECT 
			c.*, 
			UNIX_TIMESTAMP(date_posted) AS ts,
			IFNULL(u.username, c.name) AS name,
			IF(u.email IS NOT NULL, '', c.email) AS email
		FROM 
			{$this->tbl->comment} c
		LEFT JOIN {$this->tbl->user} u ON u.id = c.user_id
		WHERE 1 
			AND c.entry_id = %d
			AND c.active = 1
		ORDER BY date_posted DESC";
		return sprintf($sql, $entry_id);
	}
	
	
	function getCommentListCountSql($entry_id) {
		$sql = "SELECT COUNT(*) AS num
		FROM {$this->tbl->comment} c
		WHERE c.entry_id = %d
		AND c.active = 1
		ORDER BY date_posted DESC";
		return sprintf($sql, $entry_id);
	}
	
	
	function getCommentList($entry_id, $limit, $offset) {
		$sql = $this->getCommentListSql($entry_id);
		$result =& $this->db->SelectLimit($sql, $limit, $offset) or die(db_error($sql));
		return $result->GetArray();
	}
	
	
	// just to know if any comment exists
	function isComments($entry_id) {
		$sql = $this->getCommentListCountSql($entry_id);
		$result =& $this->db->Execute($sql) or die(db_error($sql));
		return $result->Fields('num');
	}
	
	
	// ACTIONS // ------------------------------
	
	function addComment($entry_id, $data, $status) {

		$user_id = ($this->user_id) ? $this->user_id : 'NULL';
		
		$sql = "INSERT {$this->tbl->comment} SET
		entry_id = '$entry_id',
		user_id = $user_id,
		date_posted = NOW(),
		name    = '$data[name]', 
		email   = '$data[email]',
		comment = '$data[comment]',
		active = '$status'";
		
		$this->db->Execute($sql) or die(db_error($sql));
	}

	
	function addContactMessage($data) {
	
		$user_id = ($this->user_id) ? $this->user_id : 'NULL';
	
		$sql = "INSERT {$this->tbl->feedback} SET
		user_id = $user_id,
		question = '$data[message]',
		attachment = '$data[attachment]',
		email = '$data[email]',
		name = '$data[name]',
		category_id = '$data[category_id]',
		date_posted = NOW()";
		
		$this->db->Execute($sql) or die(db_error($sql));
	}	


	function addVote($entry_id, $rate) {
		
		$action = ($this->isEntryVoted($entry_id)) ? 'UPDATE' : 'INSERT';
		
		if($action == 'UPDATE') {
			$sql = "UPDATE {$this->tbl->rating} SET
			votes    = votes+1, 
			rate     = rate+{$rate}
			WHERE entry_id = {$entry_id}";
		
		} else {
			$sql = "INSERT {$this->tbl->rating} SET
			entry_id = {$entry_id}, 
			votes    = 1, 
			rate     = {$rate}";
		}
		
		$this->db->Execute($sql) or die(db_error($sql));
	}
	
	
	function addView($entry_id) {
		$sql = "UPDATE {$this->tbl->entry} SET 
		hits = hits+1, 
		date_updated=date_updated 
		WHERE id = ?";
		$this->db->Execute($sql, $entry_id) or die(db_error($sql));
	}	
	
	
	// if article was already voted 
	function isEntryVoted($entry_id) {
		$sql = "SELECT entry_id FROM {$this->tbl->rating} WHERE	entry_id = ?";
		$result = &$this->db->Execute($sql, $entry_id) or die(db_error($sql));
		return $result->Fields('entry_id');
	}
	
	
	// check if user already vore
	function isUserVoted($entry_id) {
		$ret = false;

		if(isset($_SESSION[$this->session_vote_name])) {
			if(in_array($entry_id, $_SESSION[$this->session_vote_name])) {
				$ret = true;
			}
		}
		
		return $ret;
	}
	
	
	function setUserVoted($entry_id) {
		$_SESSION[$this->session_vote_name][] = $entry_id;
	}
	
	
	function setUserViewed($entry_id) {
		$_SESSION[$this->session_view_name][] = $entry_id;
	}
	
	
	// check if user already view
	function isUserViewed($entry_id) {
		$ret = false;
		
		if(isset($_SESSION[$this->session_view_name])) {
			if(in_array($entry_id, $_SESSION[$this->session_view_name])) {
				$ret = true;
			}
		}
		
		return $ret;
	}
	
	
	function isFlood($sec = 30) {
		$ret = false;
		
		if(!empty($_SESSION['flood_'])) {
			
			$time_to_check = $_SESSION['flood_']+$sec;
			if($time_to_check > time()) {
				$ret = $time_to_check - time();
			} else {
				$_SESSION['flood_'] = time();
			}
			
		} else {
			$_SESSION['flood_'] = time();
		}
		
		return $ret;
	}
	
	
	// it could diif in in other views
	function setCustomSettings() { }	

/*
	function isFlood($sec = 30) {
		require_once 'eleontev/Util/Antiflood.php';
		
		$af = new Antiflood(APP_CACHE_DIR);
		$af->af_prefix = "flood_";      
		$af->af_rules = array($sec => 1); // no more 1 message per 30 seconds
		return $af->getTimeout();			
	}
*/
	
	
	// MAIL // ---------------------------------
	
	function sendContactNotification($vars, $view) {
		
		require_once APP_CLIENT_DIR . 'client/inc/KBClientMailSender.php';
		
		if($this->is_registered) {
			$data = $view->stripVars($this->getUserInfo($this->user_id));
			$vars = array_merge($data, $vars);
			$vars['name'] =  $vars['first_name'] . ' ' . $vars['last_name'];
		}

		if(!$this->getSetting('contact_attachment_email')) {
			$vars['attachment'] = array();
		}
		
		$m = new KBClientMailSender();
		return $m->sendContactNotification($vars);
	}	
	
	
	function sendToFriend($vars) {
		
		require_once APP_CLIENT_DIR . 'client/inc/KBClientMailSender.php';
		
		$m = new KBClientMailSender();
		return $m->sendToFriend($vars);
	}	
	
	
	function sendConfirmRegistration($vars, $view) {
		
		require_once APP_CLIENT_DIR . 'client/inc/KBClientMailSender.php';
		
		$view_key = $view->controller->view_key;
		$vars['link'] = sprintf("%s?%s=confirm&ec=%s", APP_CLIENT_PATH, $view_key, md5($vars['email']));
		
		$m = new KBClientMailSender();
		return $m->sendConfirmRegistration($vars);
	}
	
	
	function sendGeneratedPassword($password, $vars, $view) {
		
		require_once APP_CLIENT_DIR . 'client/inc/KBClientMailSender.php';

		$vars['link'] = $view->_getLink('login');
		$vars['password'] = $password;
		
		$m = new KBClientMailSender();
		return $m->sendGeneratedPassword($vars);
	}
}
?>